package EA.testproblems;
import EA.*;
import RKUjava.lang.*;

/**
<table border="0" cellpadding="2" cellspacing="0">
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem description</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top" width="200"><b>Name:</b></td>
  <td valign="top">Ursem multimodal 8 - 50D</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Nickname:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Intended usage:</b></td>
  <td valign="top">Scalable testproblem where the peaks are not located on
  axis-parallel lines.
</td>
</tr>

<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem details</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Function:</b></td>
  <td valign="top">2*cos(2pi*(x1*x2*...*xn)) - 4*(sum_{i=1}^{n}(xi+1)**2) + (2/n)*sum_{i=1}^{n}(cos(2pi*x_i))
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Plots:</b></td>
  <td valign="top"><img src="../../images/testproblems/ursemmultimodal8.gif">&nbsp;&nbsp;
<img src="../../images/testproblems/ursemmultimodal8_contour.gif"></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Ranges:</b></td>
  <td valign="top">x = [-5:5]&nbsp;&nbsp;y = [-5:5] </td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Type:</b></td>
  <td valign="top">Maximization</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of maxima:</b></td>
  <td valign="top">Many</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of minima:</b></td>
  <td valign="top">Many</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum radius:</b></td>
  <td valign="top">0.2
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum descriptions:</b></td>
  <td valign="top">The global maxima and most of the local maximas are 
  located at one end of the search space. Some of these maximas are
  hard to detect.
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Known optima:</b></td>
  <td valign="top">
  GMAX(-1,-1,...,-1),
<br><font size=1>Capital letters 
means that the precise optimum is known, lowercase letters is the best known 
so far.</font></td>
</tr>
<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Plotting details</b></td>
</tr>

<tr bgcolor="#e0e0e0">
  <td valign="top"><b>GNUPlot code:</b></td>
  <td valign="top">
  set hidden3d<br>
  set isosamples 50<br>
  set view 70,15<br>
splot [-5:5] [-5:5] (2*cos(2*pi*x*y) - 4*((x+1)**2+(y+1)**2))+1*(cos(2*pi*x)+cos(2*pi*y))
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Latex code:</b></td>
  <td valign="top">
</td>
</tr>

</table>
*/
public class UrsemMultimodal8_50D extends NumericalProblem
{

  // Easier way to build max
  private double[][] lmax =  {{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
			       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
			       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
			       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
			       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}};

  private double[][] lmin =  {};

  public UrsemMultimodal8_50D()
    {
      super();

      double[] optimums;
      int j; 

      name = "Ursem Multimodal 8 - 50D";
      objectivefunction = new NumericalFitness(){
	      public double Fitness_calcFitness_inner(double[] realpos)
	      {
		  int i; 
		  double tmp;
		  double res = 0;

		  tmp = 1;
		  for (i=0;i<realpos.length; i++) {
		      tmp = tmp*realpos[i];
		  }

		  res = 2*Math.cos(RKUMath.TWOPI*tmp);

		  tmp = 0;
		  for (i=0;i<realpos.length; i++) {
		      tmp += (realpos[i]+1)*(realpos[i]+1);
		  }

		  res = res - 4*tmp;

		  tmp = 0;
		  for (i=0;i<realpos.length; i++) {
		      tmp += Math.cos(RKUMath.TWOPI*realpos[i]);
		  }

		  res = res + (2.0*tmp)/realpos.length;

		  return res;

	      };
	  };

      dimensions = 50;
      ismaximization = true;
      optimumradius = 0.2;

      intervals = new Interval[dimensions];
      for (j=0;j<dimensions;j++) {
	intervals[j] = new Interval(-5,5);
      }

      // Set up known maximas
      knownmaxima = new NumericalOptimum[lmax.length];

      for (j=0;j<lmax.length;j++) {
	optimums = new double[dimensions];
	optimums[0] = lmax[j][0];
	optimums[1] = lmax[j][1];
	knownmaxima[j] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), true, false, j);
      }

      // Set up known minimas
      knownminima = new NumericalOptimum[lmin.length];

      for (j=0;j<lmin.length;j++) {
	optimums = new double[dimensions];
	optimums[0] = lmin[j][0];
	optimums[1] = lmin[j][1];
	knownminima[j] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), false, false, j);
      }
    }
}
